import { Injectable, Injector } from '@angular/core';
import { Menu } from '@delon/theme';
import { BaseService } from '@shared';

@Injectable({
  providedIn: 'root'
})
export class MenuManagerService extends BaseService {
  // 新增/更新菜单
  $api_add_one = `/api/mdc/cuc/functionInfo/saveFunctionInfo`;
  // 根据应用ID获取所有菜单
  $api_get_all = `/api/mdc/cuc/functionInfo/getAllFunctionInfoByAppId`;
  // 获取菜单详情
  $api_get_menu_by_id = `/api/mdc/cuc/functionInfo/getFunctionInfo`;
  // 根据应用ID获取菜单
  $api_get_one = `/api/mdc/cuc/functionInfo/getAllFunctionInfoByAppId?_allow_badcode=true`;
  // 删除多个菜单
  $api_del_many = `/api/mdc/cuc/functionInfo/deletebatchFunctionInfo`;

  // 获取菜单下按钮权限列表
  $api_get_functions_by_id = `/api/mdc/cuc/functionButton/getFunctionButtonByFunctionId`;
  // 获取所有按钮信息
  $api_get_functions = `/api/mdc/cuc/buttonInfo/getButtonInfoList`;
  // 保存菜单按钮关联
  $api_save_menu_function = `/api/mdc/cuc/functionButton/saveFunctionButton`;
  // 删除菜单按钮关联表
  $api_delete_menu_function = `/api/mdc/cuc/functionButton/deletebatch`;
  // 排序菜单
  $api_alterFunctionsParent = `/api/mdc/cuc/functionInfo/alterFunctionsParent`;

  constructor(public injector: Injector) {
    super(injector);
  }

  getMenuByAppID(appId: string) {
    this.request(this.$api_get_one, { appId }, 'POST', false).subscribe(res => {
      if (res) {
        const menus = res.data;
        if (res.data?.length > 0) {
          this.deleteMenuByAppID(res.data);
        } else {
          this.msgSrv.success('菜单已清空');
        }
      }
    });
  }

  deleteMenuByAppID(arr: Array<any>) {
    let ids: any[] = arr?.map(item => item.id) || [];
    arr.forEach(item => {
      if (item.children?.length > 0) {
        this.deleteMenuByAppID(item.children);
      }
    });
    this.request(this.$api_del_many, ids).subscribe(res => {});
  }

  menuImport(enName: string, appId: string) {
    this.http.request('GET', `assets/mocks/platform/${enName}.json`).subscribe((res: any) => {
      this.addMenu(res.menu, appId);
    });
  }

  addMenu(menus: Array<Menu>, appId: string, parentId: string = '') {
    menus.forEach(r => {
      if (parentId !== '') {
        r.parentId = parentId;
      }
      this.request(this.$api_get_one, { appId }, 'POST', false).subscribe(res => {
        // 如果res.data存在，则更新菜单
        if (res.data) {
          r.id = res.data.id;
        }
        this.addOne({ appId, ...r, isLeaf: !(r.children && r.children.length > 0) }).subscribe(result => {
          if (result) {
            if (r.children && r.children.length > 0) {
              this.addMenu(r.children, appId, result.id);
            }
          }
        });
      });
    });

    // this.loadMenus(this.selectedPlatform.appId);
  }

  collapse(array: TreeNodeInterface[], data: TreeNodeInterface, $event: boolean): void {
    if (!$event) {
      if (data.children) {
        data.children.forEach(d => {
          const target = array.find(a => a.key === d.key)!;
          target.expand = false;
          this.collapse(array, target, false);
        });
      } else {
        return;
      }
    }
  }

  convertTreeToList(root: TreeNodeInterface): TreeNodeInterface[] {
    const stack: TreeNodeInterface[] = [];
    const array: TreeNodeInterface[] = [];
    const hashMap = {};
    stack.push({ ...root, level: 0, expand: true });

    while (stack.length !== 0) {
      const node = stack.pop()!;
      this.visitNode(node, hashMap, array);
      if (node.children) {
        for (let i = node.children.length - 1; i >= 0; i--) {
          stack.push({
            ...node.children[i],
            level: node.level! + 1,
            expand: false,
            parent: node,
            ...this.formatIcon(node.children[i].icon)
          });
        }
      }
    }

    return array;
  }

  visitNode(node: TreeNodeInterface, hashMap: { [key: string]: boolean }, array: TreeNodeInterface[]): void {
    if (!hashMap[node.key]) {
      hashMap[node.key] = true;
      array.push(node);
    }
  }

  private formatIcon(icon: any): { iconType: string; value: string } {
    let value = icon;
    let type = 'icon';
    // compatible `anticon anticon-user`
    if (~icon.indexOf(`anticon-`)) {
      value = value.split('-').slice(1).join('-');
    }
    if (~icon.indexOf(`iconfont`)) {
      type = 'iconfont';
    }
    return { iconType: type, value };
  }
}

export interface TreeNodeInterface {
  key: string;
  name: string;
  age?: number;
  level?: number;
  expand?: boolean;
  address?: string;
  children?: TreeNodeInterface[];
  parent?: TreeNodeInterface;
  [key: string]: any;
}
